#include <Windows.h>
#include "Definitions.h"

#include "DirectXFramework.h"

//Class and Title must be the same//
#define WINDOW_CLASS	L"MyBad"
#define WINDOW_TITLE	L"MyBad"

//GLOBAL VARIABLES//

HWND				g_hWnd;			//Window Handle//
HINSTANCE			g_hInstance;	//Application Instance Handle//
bool				g_bWindowed;	//Fullscreen Boolean//
CDirectXFramework	g_DX;			//DirectXFramework Instance//

//FUNCTIONS//

int WINAPI wWinMain(HINSTANCE hInstance,	//Application Handle//
	HINSTANCE hPrevInstance,//Previous Application Handle//
	LPTSTR lpCmdLine,		//Long Pointer to Command Line String//
	int lpCmdShow);			//Shows Value of Command//

LRESULT CALLBACK WndProc(HWND hWnd,			//Window Handle//
	UINT message,		//Incoming Message//
	WPARAM wparam,		//Message Info//
	LPARAM lparam);		//Additional Message Info//

//INITIALIZE THE WINDOW//

void InitWindow(void)
{
	//Allocate a Block of Memory for the Window//
	WNDCLASSEX wndClass;  
	ZeroMemory(&wndClass, sizeof(wndClass));

	//Set up the Window//
	wndClass.cbSize			= sizeof(WNDCLASSEX);			//Size of Window Structure//
	wndClass.lpfnWndProc	= (WNDPROC)WndProc;				//Message Callback//
	wndClass.lpszClassName	= WINDOW_TITLE;					//Class Name//
	wndClass.hInstance		= g_hInstance;					//Application Handle//
	wndClass.hCursor		= LoadCursor(NULL, IDC_ARROW);	//Default Cursor//
	wndClass.hbrBackground	= (HBRUSH)(COLOR_WINDOWFRAME);	//Background Brush//

	//Register a New Type of Window//
	RegisterClassEx(&wndClass);

	//Create the Window//
	g_hWnd = CreateWindowEx(
		NULL,
		WINDOW_CLASS,
		WINDOW_TITLE,
		WS_EX_TOPMOST | WS_POPUP,
		CW_USEDEFAULT,
		CW_USEDEFAULT,
		SCREEN_WIDTH,
		SCREEN_HEIGHT,
		NULL,
		NULL,
		g_hInstance,
		NULL);

	//Display the Window//
	ShowWindow(g_hWnd, SW_SHOW);
	UpdateWindow(g_hWnd);
}

//RUN THE MAIN LOOP//

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
{
	g_hInstance = hInstance;	//Store Application Handle//
	g_bWindowed = true;		//Full-Screen Mode//

	//Initialize the Window//
	InitWindow();

	//MSG Structure to Catch Window Messages//
	MSG msg; 
	ZeroMemory(&msg, sizeof(msg));

	//Initialize DirectX//
	g_DX.InitDX(g_hWnd, g_hInstance, g_bWindowed);

	//Timer to find and pass in delta time//
	__int64 cntsPerSec = 0;
	QueryPerformanceFrequency((LARGE_INTEGER*)&cntsPerSec);
	float secsPerCnt = 1.0f / (float)cntsPerSec;

	__int64 prevTimeStamp = 0;
	QueryPerformanceCounter((LARGE_INTEGER*)&prevTimeStamp);

	//Main Loop//
	while(msg.message != WM_QUIT)
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			TranslateMessage(&msg);
			DispatchMessage(&msg);
		}

		//Get Time//
		__int64 currTimeStamp = 0;
		QueryPerformanceCounter((LARGE_INTEGER*)&currTimeStamp);
		float dt = (currTimeStamp - prevTimeStamp) * secsPerCnt;

		//DirectX Update and Render Calls//
		g_DX.Update(dt);
		g_DX.Render(dt);

		prevTimeStamp = currTimeStamp;
	}

	//Shutdown DirectX//
	g_DX.Shutdown();

	//Unregister Window//
	UnregisterClass(WINDOW_TITLE, g_hInstance);

	//Return Successful//
	return 0;
}

//MESSAGE COMMANDS//

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wparam, LPARAM lparam)
{
	//Attempt to Handle Messages//
	switch(message)
	{
	case (WM_PAINT):
		{
			::InvalidateRect(hWnd,NULL,TRUE);
			break;
		}		
	case(WM_DESTROY):
		{
			::PostQuitMessage(0); 
			break;
		}
	case(WM_KEYDOWN):
		{
			switch(wparam)
			{
				//Escape Closes Application//
			case VK_ESCAPE:
				{
					::PostQuitMessage(0);
					break;
				}
			}
		}
	}
	//Pass to Default Handler//
	return DefWindowProc(hWnd, message, wparam, lparam);
}